/*!
 * \file WtRdmDtReaderAD.h
 * \project WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief WonderTrader高级随机数据读取器头文件
 * 
 * \details 该文件定义了WtRdmDtReaderAD类，提供高级随机数据读取功能，包括：
 *          - LMDB数据库集成：使用Lightning Memory-Mapped Database进行高性能数据读取
 *          - 多周期K线数据读取：支持分钟级(m1/m5)和日线级(d1)数据的随机访问
 *          - Tick数据读取：支持高频Tick数据的快速检索
 *          - 智能缓存机制：通过内存缓存减少数据库访问次数
 *          - 时间范围查询：支持按时间范围和数量进行数据检索
 *          - 热点数据管理：集成热点合约管理器
 *          
 *          与标准WtRdmDtReader相比，WtRdmDtReaderAD提供：
 *          - 更高的数据读取性能
 *          - 更好的内存使用效率
 *          - 更快的随机访问速度
 *          - 更智能的缓存策略
 *          - 更大的数据容量支持
 */

#pragma once
#include <string>
#include <stdint.h>
#include <boost/circular_buffer.hpp>

#include "DataDefineAD.h"

#include "../WTSUtils/WtLMDB.hpp"
#include "../Includes/FasterDefs.h"
#include "../Includes/IRdmDtReader.h"

#include "../Share/StdUtils.hpp"
#include "../Share/BoostMappingFile.hpp"

NS_WTP_BEGIN

typedef std::shared_ptr<BoostMappingFile> BoostMFPtr;	/*!< Boost内存映射文件智能指针类型 */

/*!
 * \class WtRdmDtReaderAD
 * \brief WonderTrader高级随机数据读取器
 * 
 * \details 该类实现了IRdmDtReader接口，提供基于LMDB的高性能随机数据读取功能。
 *          
 *          核心特性：
 *          - 分层数据库设计：按交易所和周期分库存储
 *          - 智能缓存机制：内存缓存热点数据，减少数据库访问
 *          - 多种查询方式：支持时间范围查询和数量查询
 *          - 热点数据管理：集成热点合约管理，优化常用数据访问
 *          
 *          数据组织结构：
 *          - K线数据：{basedir}/{period}/{exchg}/ (如 ./m1/CFFEX/)
 *          - Tick数据：{basedir}/ticks/{exchg}/{code}/ (如 ./ticks/CFFEX/IF2101/)
 *          
 *          缓存策略：
 *          - K线缓存：按合约和周期缓存最近访问的K线数据
 *          - Tick缓存：按合约缓存最近访问的Tick数据
 *          - 时间戳跟踪：记录缓存数据的时间范围，智能更新
 * 
 * \note 该类主要用于策略回测和实时数据分析场景
 * \see IRdmDtReader, WtLMDB
 */
class WtRdmDtReaderAD : public IRdmDtReader
{
public:
	/*!
	 * \brief 构造函数
	 */
	WtRdmDtReaderAD();
	
	/*!
	 * \brief 析构函数
	 */
	virtual ~WtRdmDtReaderAD();

//////////////////////////////////////////////////////////////////////////
//IRdmDtReader接口实现
public:
	/*!
	 * \brief 初始化随机数据读取器
	 * \param cfg 配置参数
	 * \param sink 回调接口
	 */
	virtual void init(WTSVariant* cfg, IRdmDtReaderSink* sink);

	/*!
	 * \brief 读取订单明细数据切片（按时间范围）
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间（0表示到最新）
	 * \return 订单明细数据切片（当前实现返回NULL）
	 * 
	 * \note 当前高级版本不支持订单明细数据读取
	 */
	virtual WTSOrdDtlSlice*	readOrdDtlSliceByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override { return NULL; }
	
	/*!
	 * \brief 读取订单队列数据切片（按时间范围）
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间（0表示到最新）
	 * \return 订单队列数据切片（当前实现返回NULL）
	 * 
	 * \note 当前高级版本不支持订单队列数据读取
	 */
	virtual WTSOrdQueSlice*	readOrdQueSliceByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override { return NULL; }
	
	/*!
	 * \brief 读取成交数据切片（按时间范围）
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间（0表示到最新）
	 * \return 成交数据切片（当前实现返回NULL）
	 * 
	 * \note 当前高级版本不支持成交数据读取
	 */
	virtual WTSTransSlice*	readTransSliceByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override { return NULL; }

	/*!
	 * \brief 读取Tick数据切片（按时间范围）
	 * \param stdCode 标准合约代码
	 * \param stime 开始时间
	 * \param etime 结束时间（0表示到最新）
	 * \return Tick数据切片
	 */
	virtual WTSTickSlice*	readTickSlicesByRange(const char* stdCode, uint64_t stime, uint64_t etime = 0) override;
	
	/*!
	 * \brief 读取K线数据切片（按时间范围）
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \param stime 开始时间
	 * \param etime 结束时间（0表示到最新）
	 * \return K线数据切片
	 */
	virtual WTSKlineSlice*	readKlineSliceByRange(const char* stdCode, WTSKlinePeriod period, uint64_t stime, uint64_t etime = 0) override;

	/*!
	 * \brief 读取Tick数据切片（按数量）
	 * \param stdCode 标准合约代码
	 * \param count 数据数量
	 * \param etime 结束时间（0表示到最新）
	 * \return Tick数据切片
	 */
	virtual WTSTickSlice*	readTickSlicesByCount(const char* stdCode, uint32_t count, uint64_t etime = 0) override;
	
	/*!
	 * \brief 读取K线数据切片（按数量）
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \param count 数据数量
	 * \param etime 结束时间（0表示到最新）
	 * \return K线数据切片
	 */
	virtual WTSKlineSlice*	readKlineSliceByCount(const char* stdCode, WTSKlinePeriod period, uint32_t count, uint64_t etime = 0) override;

private:
	std::string		_base_dir;			/*!< 数据库根目录 */
	IBaseDataMgr*	_base_data_mgr;		/*!< 基础数据管理器 */
	IHotMgr*		_hot_mgr;			/*!< 热点合约管理器 */

	/*!
	 * \struct _BarsList
	 * \brief K线数据缓存结构
	 * 
	 * 用于缓存某个合约特定周期的K线数据，包括元数据和实际数据
	 */
	typedef struct _BarsList
	{
		std::string		_exchg;				/*!< 交易所代码 */
		std::string		_code;				/*!< 合约代码 */
		WTSKlinePeriod	_period;			/*!< K线周期 */
		uint64_t		_last_bar_time;		/*!< 最后一根K线时间戳 */

		std::vector<WTSBarStruct>	_bars;	/*!< K线数据向量 */

		_BarsList() :_last_bar_time(0){}
	} BarsList;

	/*!
	 * \struct _TicksList
	 * \brief Tick数据缓存结构
	 * 
	 * 用于缓存某个合约的Tick数据，包括时间范围和实际数据
	 */
	typedef struct _TicksList
	{
		std::string		_exchg;				/*!< 交易所代码 */
		std::string		_code;				/*!< 合约代码 */
		uint64_t		_first_tick_time;	/*!< 第一个Tick时间戳 */
		uint64_t		_last_tick_time;	/*!< 最后一个Tick时间戳 */

		std::vector<WTSTickStruct>	_ticks;	/*!< Tick数据向量 */

		_TicksList() :_last_tick_time(0), _first_tick_time(UINT64_MAX){}
	} TicksList;

	typedef faster_hashmap<std::string, BarsList> BarsCache;	/*!< K线缓存映射表类型 */
	BarsCache	_bars_cache;		/*!< K线数据缓存，key为"exchg.code.period"格式 */

	typedef faster_hashmap<std::string, TicksList> TicksCache;	/*!< Tick缓存映射表类型 */
	TicksCache	_ticks_cache;		/*!< Tick数据缓存，key为"exchg.code"格式 */

private:
	//////////////////////////////////////////////////////////////////////////
	/*!
	 * \brief LMDB数据库定义和组织结构
	 * 
	 * \details 数据库组织方式：
	 *          - K线数据：按交易所每个周期(m1/m5/d1)分别建立一个数据库，路径如：./m1/CFFEX
	 *          - Tick数据：每个合约一个数据库，路径如：./ticks/CFFEX/IF2101
	 */
	typedef std::shared_ptr<WtLMDB> WtLMDBPtr;		/*!< LMDB数据库智能指针类型 */
	typedef faster_hashmap<std::string, WtLMDBPtr> WtLMDBMap;	/*!< LMDB数据库映射表类型 */

	WtLMDBMap	_exchg_m1_dbs;		/*!< 1分钟K线数据库映射表，key为交易所代码 */
	WtLMDBMap	_exchg_m5_dbs;		/*!< 5分钟K线数据库映射表，key为交易所代码 */
	WtLMDBMap	_exchg_d1_dbs;		/*!< 日线K线数据库映射表，key为交易所代码 */

	WtLMDBMap	_tick_dbs;			/*!< Tick数据库映射表，key为"exchg.code"格式，如"BINANCE.BTCUSDT" */

	/*!
	 * \brief 获取K线数据库实例
	 * \param exchg 交易所代码
	 * \param period K线周期
	 * \return LMDB数据库智能指针
	 */
	WtLMDBPtr	get_k_db(const char* exchg, WTSKlinePeriod period);

	/*!
	 * \brief 获取Tick数据库实例
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return LMDB数据库智能指针
	 */
	WtLMDBPtr	get_t_db(const char* exchg, const char* code);
};

NS_WTP_END
